#pragma once

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/make_shared.hpp>



#define SHARED(type) \
	typedef boost::shared_ptr<type>         ptr; \
	typedef boost::shared_ptr<const type>   const_ptr; \
	typedef boost::weak_ptr<type>           weak_ptr;


#define MAKE_SHARED(type) \
	friend boost::shared_ptr<type> boost::make_shared<type>(); \
	static boost::shared_ptr<type> create() { \
		auto obj = boost::make_shared<type>(); \
		obj->post_create(obj); \
		return obj; \
	}

#define MAKE_SHARED1(type, arg1) \
	friend boost::shared_ptr<type> boost::make_shared<type, arg1>(arg1 const &); \
	static boost::shared_ptr<type> create(arg1 const & a1) { \
		auto obj = boost::make_shared<type>(a1); \
		obj->post_create(obj); \
		return obj; \
	}

#define MAKE_SHARED2(type, arg1, arg2) \
	friend boost::shared_ptr<type> boost::make_shared<type, arg1, arg2>(arg1 const &, arg2 const &); \
	static boost::shared_ptr<type> create(arg1 const & a1, arg2 const & a2) { \
		auto obj = boost::make_shared<type>(a1, a2); \
		obj->post_create(obj); \
		return obj; \
	}

#define MAKE_SHARED3(type, arg1, arg2, arg3) \
	friend boost::shared_ptr<type> boost::make_shared<type, arg1, arg2, arg3>(arg1 const &, arg2 const &, arg3 const &); \
	static boost::shared_ptr<type> create(arg1 const & a1, arg2 const & a2, arg3 const & a3) { \
		auto obj = boost::make_shared<type>(a1, a2, a3); \
		obj->post_create(obj); \
		return obj; \
	}

#define MAKE_SHARED4(type, arg1, arg2, arg3, arg4) \
	friend boost::shared_ptr<type> boost::make_shared<type, arg1, arg2, arg3, arg4>(arg1 const &, arg2 const &, arg3 const &, arg4 const & a4); \
	static boost::shared_ptr<type> create(arg1 const & a1, arg2 const & a2, arg3 const & a3, arg4 const & a4) { \
		auto obj = boost::make_shared<type>(a1, a2, a3, a4); \
		obj->post_create(obj); \
		return obj; \
	}

#define MAKE_SHARED5(type, arg1, arg2, arg3, arg4, arg5) \
	friend boost::shared_ptr<type> boost::make_shared<type, arg1, arg2, arg3, arg4, arg5>(arg1 const &, arg2 const &, arg3 const &, arg4 const & a4, arg5 const & a5); \
	static boost::shared_ptr<type> create(arg1 const & a1, arg2 const & a2, arg3 const & a3, arg4 const & a4, arg5 const & a5) { \
		auto obj = boost::make_shared<type>(a1, a2, a3, a4, a5); \
		obj->post_create(obj); \
		return obj; \
	}

#define MAKE_SHARED6(type, arg1, arg2, arg3, arg4, arg5, arg6) \
	friend boost::shared_ptr<type> boost::make_shared<type, arg1, arg2, arg3, arg4, arg5, arg6>(arg1 const &, arg2 const &, arg3 const &, arg4 const & a4, arg5 const & a5, arg6 const & a6); \
	static boost::shared_ptr<type> create(arg1 const & a1, arg2 const & a2, arg3 const & a3, arg4 const & a4, arg5 const & a5, arg6 const & a6) { \
		auto obj = boost::make_shared<type>(a1, a2, a3, a4, a5, a6); \
		obj->post_create(obj); \
		return obj; \
	}

#define MAKE_SHARED7(type, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
	friend boost::shared_ptr<type> boost::make_shared<type, arg1, arg2, arg3, arg4, arg5, arg6, arg7>(arg1 const &, arg2 const &, arg3 const &, arg4 const & a4, arg5 const & a5, arg6 const & a6, arg7 const & a7); \
	static boost::shared_ptr<type> create(arg1 const & a1, arg2 const & a2, arg3 const & a3, arg4 const & a4, arg5 const & a5, arg6 const & a6, arg7 const &a7) { \
		auto obj = boost::make_shared<type>(a1, a2, a3, a4, a5, a6, a7); \
		obj->post_create(obj); \
		return obj; \
	}

#define MAKE_SHARED8(type, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
	friend boost::shared_ptr<type> boost::make_shared<type, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8>(arg1 const &, arg2 const &, arg3 const &, arg4 const & a4, arg5 const & a5, arg6 const & a6, arg7 const & a7, arg8 const & a8); \
	static boost::shared_ptr<type> create(arg1 const & a1, arg2 const & a2, arg3 const & a3, arg4 const & a4, arg5 const & a5, arg6 const & a6, arg7 const &a7, arg8 const & a8) { \
		auto obj = boost::make_shared<type>(a1, a2, a3, a4, a5, a6, a7, a8); \
		obj->post_create(obj); \
		return obj; \
	}

#define MAKE_SHARED9(type, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
	friend boost::shared_ptr<type> boost::make_shared<type, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9>(arg1 const &, arg2 const &, arg3 const &, arg4 const & a4, arg5 const & a5, arg6 const & a6, arg7 const & a7, arg8 const & a8, arg9 const & a9); \
	static boost::shared_ptr<type> create(arg1 const & a1, arg2 const & a2, arg3 const & a3, arg4 const & a4, arg5 const & a5, arg6 const & a6, arg7 const &a7, arg8 const & a8, arg9 const & a9) { \
		auto obj = boost::make_shared<type>(a1, a2, a3, a4, a5, a6, a7, a8, a9); \
		obj->post_create(obj); \
		return obj; \
	}
